package com.cashmama.market.api.application.filters;

import com.cashmama.market.api.application.interceptors.RequestWrapper;
import com.cashmama.market.api.application.interceptors.ResponseWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.util.UUID;

@Component
@WebFilter(urlPatterns = "/*", filterName = "logFilter")
public class LogFilter extends OncePerRequestFilter {
    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filter) {
        String traceId = UUID.randomUUID().toString().replaceAll("-", "");
        try {
            if (request.getRequestURI().contains("face/liveness_anti_hack") || request.getRequestURI().contains("picture/upload")) {
                logger.info("=== logfilter uri:{} ===", request.getRequestURI());
                filter.doFilter(request, response);
                return;
            }
            Long startTime = System.currentTimeMillis();

            MDC.put("traceId", traceId);
            ResponseWrapper responseWrapper = new ResponseWrapper(response);
            RequestWrapper requestWrapper = new RequestWrapper(request);

            filter.doFilter(requestWrapper, responseWrapper);
            String responseBody = new String(responseWrapper.getResponseData());
            //解决可能在运行的过程中页面只输出一部分
            response.setContentLength(-1);
            PrintWriter out = response.getWriter();
            out.write(responseBody);
            out.flush();
            out.close();

            BufferedReader bufferedReader = requestWrapper.getReader();
            String line;
            StringBuilder requestBody = new StringBuilder();
            while ((line = bufferedReader.readLine()) != null) {
                requestBody.append(line);
            }
            Long costTime = System.currentTimeMillis() - startTime;
            String requestURI = request.getRequestURI();
            String basicParams = request.getHeader("basicParams");
            String sb = "LogFilter日志,TraceId:" + traceId +
                    "||method:" + request.getMethod() +
                    "||url:" + requestURI +
                    "||basicParams:" + basicParams +
                    "||request:" + (requestBody.length() > 4096 ? "requestBodyTooLarge, size:" + requestBody.length() : requestBody) +
                    "||response:" + responseBody +
                    "||cost:" + costTime;
            logger.info(sb);
        } catch (Exception ex) {
            logger.error("doFilterInternal, TraceId:{}", traceId, ex);
        } finally {
            MDC.clear();
        }
    }
}
